/***********************************************
 * Modified by Xinlai,Lu on 2008/5/8
***********************************************/

#ifndef _GEOBASE_H_
#define _GEOBASE_H_

//--------------------
#include <cmath>
#include "mathbase.h"
#include <iostream>
using namespace std;
//--------------------


namespace visualization
{
class Vector;
class Point
{
public:
/******************************************/
	double getX(){return x;}
	double getY(){return y;}
	double getZ(){return z;}
/*-------------lu,xinlai,2008/5/8-----------
*******************************************/
public:
	double x, y, z;

	Point(double i_x = 0, double i_y = 0, double i_z = 0)
		: x(i_x), y(i_y), z(i_z) { }

	Point & operator+=(const Vector &v);
	Point & operator-=(const Vector &v);

	double Distance(const Point &pnt);
//----------------------------------------------------------------------------
	void setCoordinates(double xx, double yy, double zz);
	Point operator=(Point pnt);
	Point operator+(Point pnt);
	Point operator-(Point pnt);
	Point operator*(double scale);
	Point operator/(double scale);
	Point &operator+=(Point &pnt);
	Point &operator-=(Point &pnt);
	Point &operator*=(double scale);
	Point &operator/=(double scale);
	bool operator==(const Point &pnt)
	{
		return ( abs(x-pnt.x) < 1e-5 && abs(y-pnt.y) < 1e-5 && abs(z-pnt.z) < 1e-5 );
	}
	// Parameter pos gives the position of the head of the arrow.
	// end gives the two ends of the arrow.
	void drawArrow(Point pos, Point dir, Point end[2]);

// Regard the point as a vector, and rotate it by an angle "thita"
	Point &rotate(double thita);
	
//---------------------------------------------------------lu,xinlai----------
};
Point linearInterpolation(Point &highPnt, Point &lowPnt, double ratio);
class Vector
{
public:
	double x;
	double y;
	double z;

	Vector(double i_x = 0, double i_y = 0, double i_z = 0)
		: x(i_x), y(i_y), z(i_z) { }

	Vector & operator+=(const Vector &v);
	Vector & operator-=(const Vector &v);
	Vector & operator*=(double scale);
	Vector & operator/=(double scale);

	double Norm() const;
	void Normalize();

	void Cross(const Vector &rhs);

	static const Vector Cross(const Vector &lhs, const Vector &rhs);

	static inline double Dot(const Vector &lhs, const Vector &rhs)
	{ return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z; }
};

const Point operator+(const Point &lhs, const Vector &rhs);
const Point operator-(const Point &lhs, const Vector &rhs);

const Vector operator-(const Point &lhs, const Point &rhs);

const Vector operator+(const Vector &lhs, const Vector &rhs);
const Vector operator-(const Vector &lhs, const Vector &rhs);
const Vector operator*(const Vector &lhs, double rhs);
const Vector operator/(const Vector &lhs, double rhs);

}

#endif

